home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mush-7.1.1 / execute.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  4.1 KB  |  173 lines

  1. /* execute.c     (c) copyright    10/28/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. #ifdef BSD
  5. #include <sys/wait.h>
  6. #else
  7. #ifndef SYSV
  8. #include <wait.h>
  9. #endif /* SYSV */
  10. #endif /* BSD */
  11.  
  12. #ifdef lint
  13. #include <sys/resource.h>
  14. #endif /* lint */
  15.  
  16. static jmp_buf execjbuf;
  17.  
  18. #ifdef SUNTOOL
  19.  
  20. /*ARGSUSED*/
  21. static
  22. Notify_value
  23. my_wait3(tty, pid, status, rusage)
  24. Tty tty;
  25. int pid;
  26. union wait *status;
  27. struct rusage *rusage;
  28. {
  29.     extern Panel_item edit_item;
  30.     Textsw textsw = (Textsw)window_get(tty, WIN_CLIENT_DATA);
  31.     char *file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
  32.     int i = 0;
  33.  
  34.     if (WIFSTOPPED(*status)) {
  35.     kill(pid, SIGCONT);
  36.     return (NOTIFY_IGNORED);
  37.     }
  38.     if (pid != exec_pid || exec_pid <= 0) /* if the editor didn't die, return */
  39.     return NOTIFY_DONE;
  40.     /* editor died -- reset exec_pid so no one thinks we're running */
  41.     exec_pid = 0;
  42.     (void) window_set(tty, TTY_ARGV, TTY_ARGV_DO_NOT_FORK, NULL);
  43.     wprint("Editor done.\n");
  44.     (void) window_set(tty_sw, WIN_SHOW, FALSE, NULL);
  45. #ifdef SUN_4_0 /* SunOS 4.0+ */
  46.     (void) window_set(textsw,
  47.     WIN_SHOW,        TRUE,
  48.     TEXTSW_FILE_CONTENTS,    file,
  49.     NULL);
  50. #else /* SUN_4_0 */
  51.     textsw_load_file(textsw, file, 1, 0, 0);
  52.     textsw_set(textsw, WIN_SHOW, TRUE, NULL);
  53. #endif /* SUN_4_0 */
  54.     textsw_normalize_view(textsw, (Textsw_index)0);
  55.     (void) unlink(file);
  56.     set_comp_items(panel_get(edit_item, PANEL_PARENT_PANEL));
  57.  
  58.     return NOTIFY_DONE;
  59. }
  60.  
  61. tool_edit_letter(textsw, argv)
  62. Textsw textsw;
  63. char **argv;
  64. {
  65.     Rect *msg_rect = (Rect *)window_get(textsw, WIN_RECT);
  66.  
  67.     wprint("Starting \"%s\"...\n", *argv);
  68. #ifdef SUN_4_0
  69.     window_set(textsw, WIN_SHOW, FALSE, NULL);
  70. #else /* SUN_4_0 */
  71.     textsw_set(textsw, WIN_SHOW, FALSE, NULL);
  72. #endif /* SUN_4_0 */
  73.     ttysw_output(tty_sw, "\f", 1);  /* clear screen */
  74.     (void) window_set(tty_sw,
  75.     WIN_RECT,    msg_rect,
  76.     TTY_ARGV,    argv,
  77.     WIN_SHOW,    TRUE,
  78.     NULL);
  79.     if ((exec_pid = (int) window_get(tty_sw, TTY_PID)) == -1) {
  80.     error("Couldn't execute %s", *argv);
  81.     return -1;
  82.     }
  83.     notify_set_wait3_func(tty_sw, my_wait3, exec_pid);
  84.     Debug("tty pid = %d\n", exec_pid);
  85.     return 0;
  86. }
  87. #endif /* SUNTOOL */
  88.  
  89. execute(argv)
  90. char **argv;
  91. {
  92. #ifdef SYSV
  93.     int status;
  94. #else
  95.     union wait status;
  96. #endif /* SYSV */
  97. #ifdef SIGCONT
  98.     SIGRET (*oldstop)(), (*oldcont)();
  99. #endif /* SIGCONT */
  100.     int pid;
  101.     SIGRET (*oldint)(), (*oldquit)();
  102.  
  103.     oldint = signal(SIGINT, SIG_IGN);
  104.     oldquit = signal(SIGQUIT, SIG_IGN);
  105. #ifdef SIGCONT
  106.     oldstop = signal(SIGTSTP, SIG_DFL);
  107.     oldcont = signal(SIGCONT, SIG_DFL);
  108. #endif /* SIGCONT */
  109.     turnon(glob_flags, IGN_SIGS);
  110.  
  111.     echo_on();
  112.     if (!setjmp(execjbuf)) {
  113.     if ((exec_pid = vfork()) == 0) {
  114.         (void) signal(SIGINT, SIG_DFL);
  115.         (void) signal(SIGQUIT, SIG_DFL);
  116.         (void) signal(SIGPIPE, SIG_DFL);
  117.         (void) closefileds(3);    /* close all descriptors above 2 */
  118.         execvp(*argv, argv);
  119.         if (errno == ENOENT)
  120.         print("%s: command not found.\n", *argv);
  121.         else
  122.         error(*argv);
  123.         _exit(-1);
  124.     }
  125.     /* Parent's got to do something; sigchldcatcher may also be waiting.
  126.      * This loop will usually get broken by the longjmp() (except tool),
  127.      * but in certain circumstances sigchldcatcher isn't yet active.
  128.      */
  129.     while ((pid = wait(&status)) != -1 && pid != exec_pid)
  130.         Debug("The exec loop caught a signal? (pid = %d)\n", pid);
  131.     }
  132.     /* reset our ttymodes */
  133.     echo_off();
  134.     (void) signal(SIGINT, oldint);
  135.     (void) signal(SIGQUIT, oldquit);
  136. #ifdef SIGCONT
  137.     (void) signal(SIGTSTP, oldstop);
  138.     (void) signal(SIGCONT, oldcont);
  139. #endif /* SIGCONT */
  140.     turnoff(glob_flags, IGN_SIGS);
  141. }
  142.  
  143. SIGRET
  144. sigchldcatcher()
  145. {
  146. #ifdef SYSV
  147.     int status;
  148. #else
  149.     union wait status;
  150. #endif /* SYSV */
  151.     int       pid;
  152.  
  153. #ifdef BSD
  154.     while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) {
  155.     Debug("%d died...\n", pid);
  156.     if (pid == exec_pid)
  157.         break;
  158.     }
  159. #else
  160. #ifndef SYSV
  161.     while ((pid = wait2(&status, WNOHANG)) > 0 && pid != exec_pid)
  162.     Debug("%d died...\n", pid);
  163. #else /* SYSV */
  164.     while ((pid = wait((int *)0)) > 0 && pid != exec_pid)
  165.     Debug("%d died...\n", pid);
  166. #endif /* SYSV */
  167. #endif /* BSD */
  168.     if (pid == exec_pid && pid > 0) {
  169.     exec_pid = 0;
  170.     longjmp(execjbuf, 1);
  171.     }
  172. }
  173.